package com.dustedpixels.jasmin.chips.z80;

/**
 * The Z80 processor.
 * <p>
 * Warning: This interface is designed for use by user code, and not for
 * implementation by user code. New methods may be added to this interface in
 * the future. To guarantee forward compability, implementations should extend
 * Z80ImplBase class.
 */
public interface Z80 {
    /**
     * Returns the number of cycles elapsed since some fixed moment in time. The
     * value may be negative, in case choosen moment is in the future.
     * 
     * @return the number of elapsed cycles.
     */
    long getCycles();

    /**
     * Processes single Z80 instruction. This includes extended instructions,
     * starting with CB, DD, DDCB, ED, FD and FDCB prefixes. For block
     * instructions like DJNZ, single cycle is processed. An interrupt is also
     * single instruction.
     */
    void processInstruction();

    /**
     * Processes instructions until target number of cycles is reached or
     * exceeded.
     * <p>
     * Calling this method is equivalent to the code below, but may be
     * optimised.
     * 
     * <pre>
     * while (getCycles() &lt; targetCycles)
     *     processInstruction();
     * </pre>
     * 
     * @param targetCycles
     */
    void processUntil(long targetCycles);

    /**
     * Returns the value of the A register.
     * 
     * @return the value of the A register.
     */
    byte getA();

    /**
     * Returns the value of the F register.
     * 
     * @return the value of the F register.
     */
    byte getF();

    /**
     * Returns the value of the B register.
     * 
     * @return the value of the B register.
     */
    byte getB();

    /**
     * Returns the value of the C register.
     * 
     * @return the value of the C register.
     */
    byte getC();

    /**
     * Returns the value of the D register.
     * 
     * @return the value of the D register.
     */
    byte getD();

    /**
     * Returns the value of the E register.
     * 
     * @return the value of the E register.
     */
    byte getE();

    /**
     * Returns the value of the H register.
     * 
     * @return the value of the H register.
     */
    byte getH();

    /**
     * Returns the value of the L register.
     * 
     * @return the value of the L register.
     */
    byte getL();

    /**
     * Returns the value of the PC register.
     * 
     * @return the value of the PC register.
     */
    short getPC();

    /**
     * Returns the value of the SP register.
     * 
     * @return the value of the SP register.
     */
    short getSP();

    /**
     * Returns the value of the IX register.
     * 
     * @return the value of the IX register.
     */
    short getIX();

    /**
     * Returns the value of the IY register.
     * 
     * @return the value of the IY register.
     */
    short getIY();

    /**
     * Returns the value of the I register.
     * 
     * @return the value of the I register.
     */
    byte getI();

    /**
     * Returns the value of the R register.
     * 
     * @return the value of the R register.
     */
    byte getR();

    /**
     * Returns the value of the IFF1 flag (flip-flop).
     * 
     * @return the value of the IFF1 flag.
     */
    boolean getIFF1();

    /**
     * Returns the value of the IFF2 flag (flip-flop).
     * 
     * @return the value of the IFF2 flag.
     */
    boolean getIFF2();

    /**
     * Returns the value of the IM register. Possible values are 0, 1 and 2.
     * 
     * @return the value of the IM register.
     */
    byte getIM();

    /**
     * Returns the value of the A' register.
     * 
     * @return the value of the A' register.
     */
    byte getA2();

    /**
     * Returns the value of the F' register.
     * 
     * @return the value of the F' register.
     */
    byte getF2();

    /**
     * Returns the value of the B' register.
     * 
     * @return the value of the B' register.
     */
    byte getB2();

    /**
     * Returns the value of the C' register.
     * 
     * @return the value of the C' register.
     */
    byte getC2();

    /**
     * Returns the value of the D' register.
     * 
     * @return the value of the D' register.
     */
    byte getD2();

    /**
     * Returns the value of the E' register.
     * 
     * @return the value of the E' register.
     */
    byte getE2();

    /**
     * Returns the value of the H' register.
     * 
     * @return the value of the H' register.
     */
    byte getH2();

    /**
     * Returns the value of the L' register.
     * 
     * @return the value of the L' register.
     */
    byte getL2();

    /**
     * Returns the value of the AF register pair.
     * 
     * @return The value.
     */
    short getAF();

    /**
     * Returns the value of the BC register pair.
     * 
     * @return The value.
     */
    short getBC();

    /**
     * Returns the value of the DE register pair.
     * 
     * @return The value.
     */
    short getDE();

    /**
     * Returns the value of the HL register pair.
     * 
     * @return The value.
     */
    short getHL();

    /**
     * Returns the value of the AF' register pair.
     * 
     * @return The value.
     */
    short getAF2();

    /**
     * Returns the value of the BC' register pair.
     * 
     * @return The value.
     */
    short getBC2();

    /**
     * Returns the value of the DE' register pair.
     * 
     * @return The value.
     */
    short getDE2();

    /**
     * Returns the value of the HL' register pair.
     * 
     * @return The value.
     */
    short getHL2();

    /**
     * Sets the value of the A register.
     * 
     * @param value The value to set.
     */
    void setA(byte value);

    /**
     * Sets the value of the F register.
     * 
     * @param value The value to set.
     */
    void setF(byte value);

    /**
     * Sets the value of the B register.
     * 
     * @param value The value to set.
     */
    void setB(byte value);

    /**
     * Sets the value of the C register.
     * 
     * @param value The value to set.
     */
    void setC(byte value);

    /**
     * Sets the value of the D register.
     * 
     * @param value The value to set.
     */
    void setD(byte value);

    /**
     * Sets the value of the E register.
     * 
     * @param value The value to set.
     */
    void setE(byte value);

    /**
     * Sets the value of the H register.
     * 
     * @param value The value to set.
     */
    void setH(byte value);

    /**
     * Sets the value of the L register.
     * 
     * @param value The value to set.
     */
    void setL(byte value);

    /**
     * Sets the value of the PC register.
     * 
     * @param value The value to set.
     */
    void setPC(short value);

    /**
     * Sets the value of the SP register.
     * 
     * @param value The value to set.
     */
    void setSP(short value);

    /**
     * Sets the value of the IX register.
     * 
     * @param value The value to set.
     */
    void setIX(short value);

    /**
     * Sets the value of the IY register.
     * 
     * @param value The value to set.
     */
    void setIY(short value);

    /**
     * Sets the value of the I register.
     * 
     * @param value The value to set.
     */
    void setI(byte value);

    /**
     * Sets the value of the R register.
     * 
     * @param value The value to set.
     */
    void setR(byte value);

    /**
     * Sets the value of the A' register.
     * 
     * @param value The value to set.
     */
    void setA2(byte value);

    /**
     * Sets the value of the F' register.
     * 
     * @param value The value to set.
     */
    void setF2(byte value);

    /**
     * Sets the value of the B' register.
     * 
     * @param value The value to set.
     */
    void setB2(byte value);

    /**
     * Sets the value of the C' register.
     * 
     * @param value The value to set.
     */
    void setC2(byte value);

    /**
     * Sets the value of the D' register.
     * 
     * @param value The value to set.
     */
    void setD2(byte value);

    /**
     * Sets the value of the E' register.
     * 
     * @param value The value to set.
     */
    void setE2(byte value);

    /**
     * Sets the value of the H' register.
     * 
     * @param value The value to set.
     */
    void setH2(byte value);

    /**
     * Sets the value of the L' register.
     * 
     * @param value The value to set.
     */
    void setL2(byte value);

    /**
     * Sets the value of the IM register. Possible values are 0, 1 and 2.
     * 
     * @param value The value to set.
     */
    void setIM(byte value);

    /**
     * Sets the value of the IFF1 flag (flip-flop).
     * 
     * @param value The value to set.
     */
    void setIFF1(boolean value);

    /**
     * Sets the value of the IFF2 flag (flip-flop).
     * 
     * @param value The value to set.
     */
    void setIFF2(boolean value);

    /**
     * Sets the value of the AF register.
     * 
     * @param value The value to set.
     */
    void setAF(short value);

    /**
     * Sets the value of the BC register.
     * 
     * @param value The value to set.
     */
    void setBC(short value);

    /**
     * Sets the value of the DE register.
     * 
     * @param value The value to set.
     */
    void setDE(short value);

    /**
     * Sets the value of the HL register.
     * 
     * @param value The value to set.
     */
    void setHL(short value);

    /**
     * Sets the value of the AF' register.
     * 
     * @param value The value to set.
     */
    void setAF2(short value);

    /**
     * Sets the value of the BC' register.
     * 
     * @param value The value to set.
     */
    void setBC2(short value);

    /**
     * Sets the value of the DE' register.
     * 
     * @param value The value to set.
     */
    void setDE2(short value);

    /**
     * Sets the value of the HL' register.
     * 
     * @param value The value to set.
     */
    void setHL2(short value);

    /**
     * Returns the value of the C (Carry) flag.
     * 
     * @return The value.
     */
    boolean getCFlag();

    /**
     * Returns the value of the N flag.
     * 
     * @return The value.
     */
    boolean getNFlag();

    /**
     * Returns the value of the P flag.
     * 
     * @return The value.
     */
    boolean getPFlag();

    /**
     * Returns the value of the X flag.
     * 
     * @return The value.
     */
    boolean getXFlag();

    /**
     * Returns the value of the H flag.
     * 
     * @return The value.
     */
    boolean getHFlag();

    /**
     * Returns the value of the Y flag.
     * 
     * @return The value.
     */
    boolean getYFlag();

    /**
     * Returns the value of the Z flag.
     * 
     * @return The value.
     */
    boolean getZFlag();

    /**
     * Returns the value of the S flag.
     * 
     * @return The value.
     */
    boolean getSFlag();

    /**
     * Sets the value of the C flag.
     * 
     * @param value The flag to set.
     */
    void setCFlag(boolean value);

    /**
     * Sets the value of the N flag.
     * 
     * @param value The flag to set.
     */
    void setNFlag(boolean value);

    /**
     * Sets the value of the P flag.
     * 
     * @param value The flag to set.
     */
    void setPFlag(boolean value);

    /**
     * Sets the value of the X flag.
     * 
     * @param value The flag to set.
     */
    void setXFlag(boolean value);

    /**
     * Sets the value of the H flag.
     * 
     * @param value The flag to set.
     */
    void setHFlag(boolean value);

    /**
     * Sets the value of the Y flag.
     * 
     * @param value The flag to set.
     */
    void setYFlag(boolean value);

    /**
     * Sets the value of the Z flag.
     * 
     * @param value The flag to set.
     */
    void setZFlag(boolean value);

    /**
     * Sets the value of the S flag.
     * 
     * @param value The flag to set.
     */
    void setSFlag(boolean value);
}
